# -*- coding: utf-8 -*-
"""
-------------------------------------------
    Description:
    Author:             yu_lei
    Email:              lyu@topxgun.com
    Date:               2022/03/31
-------------------------------------------
"""
import random
import sys
import time

from PyQt5 import QtWidgets
from PyQt5.QtCore import QSize, Qt, pyqtSignal
from PyQt5.QtGui import QColor, QFont
from PyQt5.QtWidgets import *
from pyqtgraph.widgets.PlotWidget import PlotWidget
import pyqtgraph as pg


class CustomCheckBox(QCheckBox):
    """
    自定义CheckBox
    """

    signal_b_checked = pyqtSignal(str, bool)  # obj_name对象名称，选中状态

    def __init__(self, parent=None, desc='', obj_name=''):
        super().__init__(desc, parent)
        self.setObjectName(obj_name)
        self.stateChanged.connect(self.slot_state_changed)

    def slot_state_changed(self, state):
        if state == Qt.CheckState.Checked:
            self.signal_b_checked.emit(self.objectName(), True)
        elif state == Qt.CheckState.Unchecked:
            self.signal_b_checked.emit(self.objectName(), False)
        else:
            return


class GraphWidgetGroup(QWidget):
    """
    图形曲线分组展示
    """
    # *中英文对应
    DICT_NAME_PAIR = {'mins_roll_rate': '滚转角速率(主惯导)', 'mins_pitch_rate': '俯仰角速率(主惯导)', 'mins_yaw_rate': '偏航角速率(主惯导)',
                      'bins_roll_rate': '滚转角速率(备惯导)', 'bins_pitch_rate': '俯仰角速率(备惯导)', 'bins_yaw_rate': '偏航角速率(备惯导)',
                      'mins_roll_angle': '滚转角(主惯导)', 'mins_pitch_angle': '俯仰角(主惯导)', 'mins_yaw_angle': '航迹角(主惯导)',
                      'mins_heading_angle': '航向角(主惯导)', 'bins_roll_angle': '滚转角(备惯导)', 'bins_pitch_angle': '俯仰角(备惯导)',
                      'gps_yaw_angle': '航迹角(GPS)', 'mins_speed_grd': '地速(主惯导)', 'gps_speed_grd': '地速(GPS)',
                      'adc_airspeed': '空速(大气机)',
                      'mins_speed_vel': '垂直速度(主惯导)', 'gps_speed_vel': '垂直速度(GPS)', 'adc_speed_vel': '垂直速度(大气机)',
                      'mins_accelerate_x': '轴向加速度(主惯导)', 'mins_accelerate_y': '侧向加速度(主惯导)',
                      'mins_accelerate_z': '法向加速度(主惯导)',
                      'bins_accelerate_x': '轴向加速度(备惯导)', 'bins_accelerate_y': '侧向加速度(备惯导)',
                      'bins_accelerate_z': '法向加速度(备惯导)',
                      'mins_alt': '海拔高度(主惯导)', 'gps_alt': '海拔高度(GPS)', 'adc_alt': '气压高度(大气机)',
                      'radar_height_1': '雷达高度1(毫米波雷达)',
                      'radar_height_2': '雷达高度2(毫米波雷达)', 'radar_height_3': '雷达高度3(毫米波雷达)', 'eng_thr': '发动机油门',
                      'eng_rpm': '发动机转速',
                      'temp_lube': '滑油温度', 'press_lube': '滑油压力', 'temp_cyl2': '2缸温度', 'temp_cyl3': '3缸温度',
                      'temp_gas1': '排气温度1',
                      'temp_gas2': '排气温度2', 'temp_gas3': '排气温度3', 'temp_gas4': '排气温度4'}
    # *分组信息
    LIST_GROUP_INFOS = [{'group_name_CN': '角速率信息', 'group_name_EN': 'AngularRateInfo',
                         'infos': ['mins_roll_rate', 'mins_pitch_rate', 'mins_yaw_rate', 'bins_roll_rate',
                                   'bins_pitch_rate', 'bins_yaw_rate']},
                        {'group_name_CN': '姿态信息', 'group_name_EN': 'PostureInfo',
                         'infos': ['mins_roll_angle', 'mins_pitch_angle', 'mins_yaw_angle', 'mins_heading_angle',
                                   'bins_roll_angle',
                                   'bins_pitch_angle', 'gps_yaw_angle']},
                        {'group_name_CN': '速度信息', 'group_name_EN': 'SpeedInfo',
                         'infos': ['mins_speed_grd', 'gps_speed_grd', 'adc_airspeed', 'mins_speed_vel', 'gps_speed_vel',
                                   'adc_speed_vel']},
                        {'group_name_CN': '加速度信息', 'group_name_EN': 'AccelerationInfo',
                         'infos': ['mins_accelerate_x', 'mins_accelerate_y', 'mins_accelerate_z', 'bins_accelerate_x',
                                   'bins_accelerate_y', 'bins_accelerate_z']},
                        {'group_name_CN': '高度信息', 'group_name_EN': 'HeightInfo',
                         'infos': ['mins_alt', 'gps_alt', 'adc_alt', 'radar_height_1', 'radar_height_2',
                                   'radar_height_3']},
                        {'group_name_CN': '发动机参数', 'group_name_EN': 'EngineParams',
                         'infos': ['eng_thr', 'eng_rpm', 'temp_lube', 'press_lube', 'temp_cyl2', 'temp_cyl3',
                                   'temp_gas1',
                                   'temp_gas2', 'temp_gas3', 'temp_gas4']}]

    # *A帧中需要展示的曲线
    LIST_INFOS_IN_ADC = ['adc_airspeed', 'adc_speed_vel', 'adc_alt']

    # *B帧中需要展示的曲线
    LIST_INFOS_IN_MINS = ['mins_roll_rate', 'mins_pitch_rate', 'mins_yaw_rate', 'mins_roll_angle',
                          'mins_pitch_angle', 'mins_yaw_angle', 'mins_heading_angle', 'mins_speed_grd',
                          'mins_speed_vel', 'mins_accelerate_x', 'mins_accelerate_y', 'mins_accelerate_z',
                          'mins_alt']
    LIST_INFOS_IN_RADAR = ['radar_height_1', 'radar_height_2', 'radar_height_3']

    # *E帧中需要展示的曲线
    LIST_INFOS_IN_ENGINE = ['eng_thr', 'eng_rpm', 'temp_lube', 'press_lube', 'temp_cyl2', 'temp_cyl3',
                            'temp_gas1', 'temp_gas2', 'temp_gas3', 'temp_gas4']

    # *F帧中需要展示的曲线
    LIST_INFOS_IN_BINS = ['bins_roll_rate', 'bins_pitch_rate', 'bins_yaw_rate', 'bins_roll_angle',
                          'bins_pitch_angle', 'bins_accelerate_x',
                          'bins_accelerate_y', 'bins_accelerate_z']
    LIST_INFOS_IN_GPS = ['gps_yaw_angle', 'gps_speed_grd', 'gps_speed_vel', 'gps_alt']

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle('图形曲线')
        # self.setWindowState(Qt.WindowState.WindowMaximized)

        # self.parser = DataHandler()
        # self.parser.receiveDataA.connect(self.slot_receive_data_a)
        # self.parser.receiveDataB.connect(self.slot_receive_data_b)
        # self.parser.receiveDataE.connect(self.slot_receive_data_e)
        # self.parser.receiveDataF.connect(self.slot_receive_data_f)

        self.dict_all_plot_infos = dict()  # * 所有绘图信息
        self.dict_plot_data_line = dict()  # * 绘图返回值，后面刷新、删除使用
        self.dict_group_name_plot_widget_pair = dict()  # * 组名和绘图界面对应
        self.dict_info_group_name_pair = dict()  # * 数据和组名对应

        self._init_ui()

        self.setStyleSheet('QGroupBox{border:1px solid;border-radius: 4px;}'
                           'QGroupBox::title{subcontrol-origin: margin;subcontrol-position: top left;left: 1em;}'
                           'QWidget{background-color: white}')

    def closeEvent(self, event):
        """[summary]
        窗口关闭初始化
        """
        for key, item in self.dict_group_name_plot_widget_pair.items():
            item.clear()

        for key in self.dict_info_group_name_pair.keys():
            self.findChild(CustomCheckBox, key).setCheckState(Qt.CheckState.Unchecked)

    def _init_ui(self):
        main_grid_layout = QGridLayout()
        main_grid_layout.setContentsMargins(10, 10, 10, 10)

        for index, group_info in enumerate(self.LIST_GROUP_INFOS):
            group_box = QGroupBox(group_info['group_name_CN'])

            group_h_layout = QHBoxLayout()
            group_h_layout.setContentsMargins(5, 15, 0, 0)

            plot_widget = PlotWidget()
            plot_widget.setBackground('w')
            plot_widget.setLabel('left', '数据信息')
            plot_widget.setLabel('bottom', '时间戳')
            plot_widget.addLegend()
            self.dict_group_name_plot_widget_pair[group_info['group_name_EN']] = plot_widget

            frame_check_box = QFrame()
            v_layout_frame = QVBoxLayout()
            v_layout_frame.setContentsMargins(0, 0, 0, 0)
            for info in group_info['infos']:
                custom_check_box = CustomCheckBox(desc=self.DICT_NAME_PAIR[info], obj_name=info)

                custom_check_box.signal_b_checked.connect(self.slot_b_checked)
                v_layout_frame.addWidget(custom_check_box)

                r = random.randint(0, 255)
                g = random.randint(0, 255)
                b = random.randint(0, 255)
                while r == 255 and g == 255 and b == 255:
                    r = random.randint(0, 255)
                    g = random.randint(0, 255)
                    b = random.randint(0, 255)

                dict_info_temp = {'b_check': False, 'color': QColor(r, g, b), 'x_data': [], 'y_data': []}
                self.dict_all_plot_infos[info] = dict_info_temp
                self.dict_info_group_name_pair[info] = group_info['group_name_EN']
            v_layout_frame.addStretch(1)
            frame_check_box.setLayout(v_layout_frame)

            group_h_layout.addWidget(frame_check_box)
            group_h_layout.addWidget(plot_widget)

            group_box.setLayout(group_h_layout)

            main_grid_layout.addWidget(group_box, index // 3, index % 3)

        self.setLayout(main_grid_layout)

    def slot_b_checked(self, obj_name, b_checked):
        # print('obj_name = ', obj_name, b_checked, flush=True)
        if b_checked:
            self.dict_all_plot_infos[obj_name]['b_check'] = True
        else:
            self.dict_all_plot_infos[obj_name]['b_check'] = False
            self.dict_all_plot_infos[obj_name]['x_data'].clear()
            self.dict_all_plot_infos[obj_name]['y_data'].clear()
            if obj_name in self.dict_plot_data_line.keys():
                self.dict_group_name_plot_widget_pair[self.dict_info_group_name_pair[obj_name]].removeItem(
                    self.dict_plot_data_line[obj_name])
                del self.dict_plot_data_line[obj_name]

    # def slot_receive_data_a(self, data):
    #     cur_timestamp_ms = int(round(time.time() * 1000))
    #     for info in self.LIST_INFOS_IN_ADC:
    #         if self.dict_all_plot_infos[info]['b_check']:
    #             self.dict_all_plot_infos[info]['x_data'].append(cur_timestamp_ms)
    #             self.dict_all_plot_infos[info]['y_data'].append(getattr(data, info))
    #             if info in self.dict_plot_data_line.keys():
    #                 self.dict_plot_data_line[info].setData(self.dict_all_plot_infos[info]['x_data'],
    #                                                        self.dict_all_plot_infos[info]['y_data'])
    #             else:
    #                 # ! 不能直接使用pen_temp = QPen(self.dict_all_plot_infos[info]['color'])
    #                 pen_temp = pg.mkPen(color=self.dict_all_plot_infos[info]['color'], width=2,
    #                                     style=Qt.PenStyle.SolidLine)
    #                 data_line = self.dict_group_name_plot_widget_pair[self.dict_info_group_name_pair[info]].plot(
    #                     self.dict_all_plot_infos[info]['x_data'],
    #                     self.dict_all_plot_infos[info]['y_data'],
    #                     name=self.DICT_NAME_PAIR[info], pen=pen_temp)  # , symbol='+'
    #                 self.dict_plot_data_line[info] = data_line
    #
    # def slot_receive_data_b(self, data):
    #     cur_timestamp_ms = int(round(time.time() * 1000))
    #     for info in self.LIST_INFOS_IN_MINS:
    #         if self.dict_all_plot_infos[info]['b_check']:
    #             self.dict_all_plot_infos[info]['x_data'].append(cur_timestamp_ms)
    #             self.dict_all_plot_infos[info]['y_data'].append(getattr(data, info))
    #             if info in self.dict_plot_data_line.keys():
    #                 self.dict_plot_data_line[info].setData(self.dict_all_plot_infos[info]['x_data'],
    #                                                        self.dict_all_plot_infos[info]['y_data'])
    #             else:
    #                 # ! 不能直接使用pen_temp = QPen(self.dict_all_plot_infos[info]['color'])
    #                 pen_temp = pg.mkPen(color=self.dict_all_plot_infos[info]['color'], width=2,
    #                                     style=Qt.PenStyle.SolidLine)
    #                 data_line = self.dict_group_name_plot_widget_pair[self.dict_info_group_name_pair[info]].plot(
    #                     self.dict_all_plot_infos[info]['x_data'],
    #                     self.dict_all_plot_infos[info]['y_data'],
    #                     name=self.DICT_NAME_PAIR[info], pen=pen_temp)  # , symbol='+'
    #                 self.dict_plot_data_line[info] = data_line
    #
    # def slot_receive_data_e(self, data):
    #     cur_timestamp_ms = int(round(time.time() * 1000))
    #     for info in self.LIST_INFOS_IN_ENGINE:
    #         if self.dict_all_plot_infos[info]['b_check']:
    #             self.dict_all_plot_infos[info]['x_data'].append(cur_timestamp_ms)
    #             self.dict_all_plot_infos[info]['y_data'].append(getattr(data, info))
    #             if info in self.dict_plot_data_line.keys():
    #                 self.dict_plot_data_line[info].setData(self.dict_all_plot_infos[info]['x_data'],
    #                                                        self.dict_all_plot_infos[info]['y_data'])
    #             else:
    #                 pen_temp = pg.mkPen(color=self.dict_all_plot_infos[info]['color'], width=2,
    #                                     style=Qt.PenStyle.SolidLine)
    #                 data_line = self.dict_group_name_plot_widget_pair[self.dict_info_group_name_pair[info]].plot(
    #                     self.dict_all_plot_infos[info]['x_data'],
    #                     self.dict_all_plot_infos[info]['y_data'],
    #                     name=self.DICT_NAME_PAIR[info], pen=pen_temp)
    #                 self.dict_plot_data_line[info] = data_line
    #
    # def slot_receive_data_f(self, data):
    #     cur_timestamp_ms = int(round(time.time() * 1000))
    #     for info in self.LIST_INFOS_IN_BINS:
    #         if self.dict_all_plot_infos[info]['b_check']:
    #             self.dict_all_plot_infos[info]['x_data'].append(cur_timestamp_ms)
    #             self.dict_all_plot_infos[info]['y_data'].append(getattr(data, info))
    #             if info in self.dict_plot_data_line.keys():
    #                 self.dict_plot_data_line[info].setData(self.dict_all_plot_infos[info]['x_data'],
    #                                                        self.dict_all_plot_infos[info]['y_data'])
    #             else:
    #                 pen_temp = pg.mkPen(color=self.dict_all_plot_infos[info]['color'], width=2,
    #                                     style=Qt.PenStyle.SolidLine)
    #                 data_line = self.dict_group_name_plot_widget_pair[self.dict_info_group_name_pair[info]].plot(
    #                     self.dict_all_plot_infos[info]['x_data'],
    #                     self.dict_all_plot_infos[info]['y_data'],
    #                     name=self.DICT_NAME_PAIR[info], pen=pen_temp)
    #                 self.dict_plot_data_line[info] = data_line


# 地面站软件的入口程序
if __name__ == '__main__':
    # 启动地面站主界面
    app = QtWidgets.QApplication(sys.argv)
    gcs_main_window = QtWidgets.QMainWindow()
    ui = GraphWidgetGroup()

    ui.show()

    sys.exit(app.exec_())
